home *** CD-ROM | disk | FTP | other *** search
- {$I-,R-,V-,U-,K-}
- program Turbo_Timer_Window;
-
- { - this is a stay-resident program providing full-screen windows
- accessed by printing commands on the screen. Date and running Clock
- as well as addl.info is placed directly into the screen memory.
- - once installed, you print a command (nS-save window N, nL-load window N)
- at the position specified by <Window_Cmd_Pos> and the program will
- save or load the desired screen next time the internal clock ticks.
- (18.2 times/sec)
- - info/date/time are updated every <Ticks_in_between> times the clock-
- interrupt occours.
- (with in_between=6 the effective clockspeed is .957% or 4.56MHz)
- - syntax :
- nc where n is the window number 0..screen_limit and
- c is the command, either S or L
- the command has to be printed at character position <Window_Cmd_Pos>
-
- - note: date is not updated
- - note: need facility (new window cmd) to change/set Info_Str,
- to enable/disable screen update, to enable/disable routine.
- }
- Type {basic Types}
- Register_Set =Record Case Integer Of
- 1: (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags: Integer);
- 2: (AL,AH,BL,BH,CL,CH,DL,DH: Byte); End;
- Any_String =String[80];
- String2 =String[2];
- String3 =String[3];
- Memory_Address =record S,O : integer ; end;
- DoW =(Sun,Mon,Tue,Wed,Thu,Fri,Sat);
- Date_Type =Record Month,Day,Year: Byte; DayOfWeek: DOW; End;
- Const {all typed constants are Vars for IRQ sub}
- Tick_Count :Integer =0;
- regs :register_set =(ax:0;bx:0;cx:0;dx:0;bp:0;si:0;di:0;ds:0;es:0;flags:0);
- saveds :integer =0;
- Screen_Ptr :String3 ='abc';
- Buffer_Ptr :String3 ='def';
- Window_Cmd :char =' ';
- Window_No :integer = 0;
- Date_Str :Any_String= '';
- Hours :integer = 0;
- Minut :integer = 0;
- Secon :integer = 0;
- i :integer = 0;
- Const
- Info_Str='Turbo_Timer_Window V1.0 Active';
- Ticks_in_between =6;{ticks between calls of our int 6=4*/sec}
- Low_Window=$30; {code letter(='0') for first window}
- High_Window=$33; {code letter(='3') for last window 4 screens}
- Screen_Size=2000; {80*25*2(Attr:Char) =4kb/screen}
- Type
- Single_Screen =array[1..Screen_Size] of Integer;
- Screen_Buffer_Type =array[Low_Window..High_Window] of Single_Screen;
- Var
- Timer_Low :Integer absolute $0040:$006C; { BIOS dependent }
- Timer_High :Integer absolute $0040:$006E;
- Screen :^Single_Screen absolute Screen_Ptr;
- Memory :^Screen_Buffer_Type absolute Buffer_Ptr;
- Const {screen Positions}
- Date_End =70;
- Window_Cmd_Pos = 71;
- Time_Pos =73;
- Const {char/attr defi}
- Blk = $0000;
- Low = $0700;
- Hig = $0F00;
- Low_Spc = $0720; { ' ' low intensity }
- Zero = $0F30; { '0' low intensity }
- Const {*bios calls*}
- Video_IO =$10;
- Video_Read_Mode =$0F;
- Timer_Int =$08;
- Terminate_Resident =$27;
- User_Int =$68; { range from $60..$67, unused int range $68..$7f }
- Const {*function calls*}
- dos_Function =$21;
- dos_Get_Date =$2A;
- dos_Get_Time =$2C;
- Ticks_Sec =18;
- Ticks_Min =546; {1092;} { actually 1092, program does div 2 before}
- Ticks_Hour =65543.0; { $10007}
- dos_Set_Vector =$25; {interrupt type AX set to DS:DX}
- dos_Get_Vector =$35; {addr interrupt AX in ES:BX}
-
- Procedure Turbo_Timer_Tick;
- begin
- {$Iregsave.inc} {save regs}
- intr(User_Int,Regs); {exec old irq}
- if Tick_Count =0 { every ticks_in_between turns date/time upd}
- then begin
- screen^[1]:=$0f6d; { put mAx }
- screen^[2]:=$0f41;
- screen^[3]:=$0f78;
- for i:= 4 to Date_End do screen^[i]:=Hig+ord(Date_Str[i]); {Put Info,Date}
- Hours:=Timer_High and $FF; { prepare Time }
- i:=Timer_Low;
- Minut:=(i and $7fff)div 2;
- if i<0 then i:=(Minut or $4000) else i:=minut;
- Minut:=i div Ticks_Min; { ticks_Min is only half of actual}
- Secon:=i mod Ticks_Min div Ticks_Sec; { kill secs for speed}
- screen^[time_pos+0]:=Zero+Hours Div 10; { put Time }
- screen^[time_pos+1]:=Zero+Hours Mod 10;
- screen^[time_pos+2]:=$8f3a;
- screen^[time_pos+3]:=Zero+Minut Div 10;
- screen^[time_pos+4]:=Zero+Minut Mod 10;
- screen^[time_pos+5]:=$8f3a;
- screen^[time_pos+6]:=Zero+Secon Div 10;
- screen^[time_pos+7]:=Zero+Secon Mod 10;
- { for i:= 81 to 160 do screen^[i]:=$0FCD; } { line of '═' }
- Tick_Count:=Ticks_in_between;
- end
- else Tick_Count:=Tick_Count-1;
- {get Window #}
- if Screen^[Window_Cmd_Pos]<>Blk
- then begin
- Window_No:=Lo(Screen^[Window_Cmd_Pos]);
- if Window_No<=High_Window
- then if Window_No>=Low_Window
- then begin
- {get command !ch}
- Window_Cmd:=chr(lo(screen^[Window_Cmd_Pos+1]) and $DF );
- {erase screen&command}
- screen^[Window_Cmd_Pos]:=Blk;
- screen^[Window_Cmd_Pos+1]:=Blk;
- case Window_Cmd of
- 'L': for I:= 1 to screen_size
- do screen^[I]:=memory^[Window_No,I];
- 'S': begin
- I:= 2;
- while i<=Screen_Size do begin
- memory^[Window_No,I]:=screen^[I];
- i:=i+2; end;
- I:= I-1;
- while i>=1 do begin
- memory^[Window_No,I]:=screen^[I];
- i:=i-2; end;
- end;
- else {restore Window Number}
- screen^[Window_Cmd_Pos]:=Hig+Window_No;
- end; {case}
- end;{if}
- end;{if}
- {$iregrstor.inc} {restore registers}
- inline($CF); {IRET and off we go}
- end;
-
- Const Mark_Buffer_Begin :Byte =$00;
- {remainder of progr only required for setup}
-
- Const
- DayName: Array [DOW] Of String[3]=
- ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
- MonName: Array [1..12] Of String[3]=
- ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
- Var
- Date_Var :Date_Type;
- Dummy :Any_String;
- Org_Timer_Tick :memory_address;
- r :Register_Set;
- Procedure Get_Date;
- Begin
- With R,Date_Var Do Begin
- AH:=dos_Get_Date; Intr(dos_Function,R);
- Month:=DH;Day:=DL;Year:=CX-1900;DayOfWeek:=DOW(AL);
- End;
- End;
- Procedure Get_Vector (intr_number:integer; var segment,offset:integer);
- begin {get the address that was there}
- with r do begin
- ah:=dos_Get_Vector;
- al:=intr_number;
- Intr(dos_Function,r);
- segment:=es;
- offset:=bx;
- end;
- end;
- Procedure Set_Vector (intr_number,segment,offset:integer);
- begin
- with r do begin
- ah:=dos_Set_Vector;
- al:=intr_number;
- ds:=segment;
- dx:=offset;
- end;
- Intr(dos_Function,r);
- end;
- Function V2(I:Integer):String2;
- Begin
- V2:=Chr(48+I Div 10)+Chr(48+I Mod 10);
- End;
- procedure prepare_interrupt;
- begin
- saveds:=Dseg; {save the data segment local}
- r.ah:=Video_Read_Mode; INTR(Video_IO,r); {determine video adapter}
- if r.al=7 {mono}
- then screen:=ptr($B000,0) else screen:=ptr($B800,0); {color}
- Memory:=Addr(Mark_Buffer_Begin); {set pointer to buffer}
- Get_Date;
- With Date_Var do
- Date_Str:= DayName[DayOfWeek]+', '+MonName[Month]+' '+V2(Day)+', 19'+V2(Year);
- Date_Str:=Info_Str+' '+Date_Str;
- while Date_Str[0]<chr(Date_End) do Date_Str:=' '+Date_Str; {shift right}
- end;
-
- Type Hex_Array = array[0..15] of Char;
- String5 = String[5];
- Const Hex_Digit :Hex_Array = '0123456789ABCDEF';
- Function Hex(V:integer):String5;
- var h:String5;
- begin
- h:='$0000';
- for i:= 4 downto 1
- do begin
- h[i+1]:=hex_Digit[v and $000F];
- v:=v div $10;
- end;
- Hex:=h;
- end;
- procedure install_interrupt;
- begin
- Get_Vector ( Timer_Int, Org_Timer_Tick.s, Org_Timer_Tick.o );
- Set_Vector ( User_Int, Org_Timer_Tick.s, Org_Timer_Tick.o );
- Set_Vector ( Timer_Int, seg(regs), ofs(Turbo_Timer_Tick) );
- {make resident. contain all. incl stack}
- r.dx:=$2+ofs(Memory^[High_Window,Screen_Size])+$400{40para stack};
- writeln( #10,#10,'to install ',hex(r.dx),' (',r.dx,') bytes hit return, hit * to cancel');
- readln(Dummy);if Dummy<>'*' then Intr(Terminate_Resident,r);
- Set_Vector ( Timer_Int, Org_Timer_Tick.s, Org_Timer_Tick.o );
- Set_Vector ( User_Int, 0,0 );
- writeln('unlinked.');
- end;
-
- begin
- prepare_interrupt;
- install_interrupt;
- end.
-
-
-
- NOTE to patch the initial turbo clear screen.
- DEBUG thisone.com :note that debug offsets $100
- E 02FC <return> 90 <space> 90 <return>
- W <return>
- Q <return>
-
- NOTE to compile this program,
- set MinDymMem I to 12 paragraphs,
- set MaxDymMem A to 40 paragraphs.
- when EBL available, use following Batch file:
- .
- bat begstack
- turbo
- YOCI12
- A40
- q
- end
- .
-
- NOTE SideKick may screw up (when popped up during? save/load)
- no other hangups found on my system. runs with spooler,VD,Network
- !! but no warranty can be given that program is error free !!
- i bet it isn't although i don't know of anything.
-
- NOTE give credit to the guy that wrote LASTCOM.pas for his demo of
- a resident turbo program and to borland's bella lubkin for INT24.pas
- both put out excellent programs which taught me a good deal about
- bios/dos programing.
-
- NOTE written by Michael Ax (718) 278-6079, trying to make dbase3
- a little bit more usefull.
-
- NOTE if you use this program, i'm sure you will change it too. please
- let me know what you did and how, maybe our ideas match. also, if
- you take it to assembler before i do, download a copy of it to
- a board where you see my name on or give me a call.
-
-
- 7/24/85 V1.0 ...let the force be with you